package vip.specimen.system.service;

import com.alibaba.fastjson.JSONObject;
import org.apache.shiro.SecurityUtils;
import org.aspectj.lang.JoinPoint;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import vip.specimen.system.datasource.entity.SystemLogEntity;
import vip.specimen.system.datasource.entity.SystemUserEntity;
import vip.specimen.system.repository.SystemLogRepository;
import vip.specimen.system.utils.CommonUtil;
import vip.specimen.system.utils.DataBaseUtil;
import vip.specimen.system.utils.ThreadPoolUtil;
import vip.specimen.system.utils.ToolUtil;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import static vip.specimen.system.utils.CommonUtil.convertArrayToString;

/**
 * *@Author: 余浪人
 * *@Date：2021/3/15 17:24
 * *@Email:yulangren520@Gmail.com
 * *@QQ:1368419640
 **/
@Service
public class SystemLogService {
    @Resource
    private SystemLogRepository logRepository;
    @Resource
    private HttpServletRequest request;

    public void insert(SystemLogEntity logEntity) {
        this.logRepository.saveAndFlush(logEntity);
    }

    public Page<SystemLogEntity> findLogAll() {
        JSONObject param = CommonUtil.pageParams(this.request);
        return this.logRepository.findAll(DataBaseUtil.getPageable(param.getIntValue("page"), param.getIntValue("pageSize"), DataBaseUtil.getSort("desc", "createTime")));
    }

    /**
     * 添加日志
     */
    public void write(String title, JoinPoint joinPoint) {
        Map<String, String[]> requestParams = request.getParameterMap();
        SystemLogEntity log = new SystemLogEntity();
        SystemUserEntity user = (SystemUserEntity) SecurityUtils.getSubject().getPrincipal();
        log.setUsername(user.getUsername());
        log.setTitle(title);
        log.setUrl(request.getRequestURI());
        log.setHttpMethod(request.getMethod());
        JSONObject params = new JSONObject(requestParams.size());
        for (Map.Entry<String, String[]> entry : requestParams.entrySet()) {
            params.put(entry.getKey(), convertArrayToString(entry.getValue()));
        }
        log.setParams(params.toJSONString());
        JSONObject json = new JSONObject();
        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String s = headerNames.nextElement();
            json.put(s, request.getHeader(s));
        }
        String header = json.toJSONString();
        log.setHeader(header);
        log.setClassMethod(joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        log.setIp(CommonUtil.getIp(request));
        HashMap<String, String> os = ToolUtil.getOsAndBrowserInfo(request);
        log.setOperatingSystem(os.get("os"));
        log.setBrower(request.getHeader("USER-AGENT"));
        ThreadPoolUtil.getPool().execute(new SaveSystemLogThread(log, this));
    }

    private static class SaveSystemLogThread implements Runnable {
        private SystemLogEntity log;
        private SystemLogService logService;

         SaveSystemLogThread(SystemLogEntity esLog, SystemLogService logService) {
            this.log = esLog;
            this.logService = logService;
        }

        @Override
        public void run() {
            logService.insert(log);
        }
    }
}
